\fs88 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i0 \fs28 This chapter gives detailed descriptions of the C functions provided by the NeXT Mach operating system. It also describes some macros that behave like functions. For this chapter, the functions and macros are divided into five groups:\
\fs20 \
\fs28 \s6 \li2494 \fi-378 \'b7 C-thread functions\'d0Use these to implement multiple threads in an application.\
\fs20 \
\fs28 \'b7 Mach kernel functions\'d0Use these to get access to the Mach operating system.\
\fs20 \
\fs28 \'b7 Bootstrap Server functions\'d0Use these to set up communication between the task that provides a local service and the tasks that use the service. \
\fs20 \
\fs28 \'b7 Network Name Server functions\'d0Use these to set up communication between tasks that might not be on the same machine. \
\fs20 \
\fs28 \'b7 Kernel-server loader functions\'d0Use these to load and unload loadable kernel servers, to add and delete servers to and from the kernel-server loader, and to get information about servers. \
\fs20 \
\fs28 \s4 \li2116 \fi0 Within each section, functions are subgrouped with other functions that perform related tasks. These subgroups are described in alphabetical order by the name of the first function listed in the subgroup. Functions within subgroups are also listed alphabetically, with a pointer to the subgroup description. \
\fs20 \
\fs28 For convenience, these functions are summarized in the \i NEXTSTEP Programming Interface Summary\i0 . The summary lists functions by the same subgroups used in this chapter and combines several related subgroups under a heading such as \'aaBasic C-Thread Functions\'ba or \'aaTask Functions.\'ba For each function, the summary shows the calling sequence.\
\fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 These functions provide a C language interface to the low-level, language-independent primitives for manipulating threads of control. \
\fs20 \
\fs28 In a multithreaded application, you should use the C-thread functions whenever possible, rather than Mach kernel functions. If you need to call a Mach kernel function that requires a \b thread_t\b0 argument, you can find the Mach thread that corresponds to a particular C thread by calling \b cthread_thread()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macros \b condition_alloc()\b0 and \b mutex_alloc()\b0 provide dynamic allocation of condition and mutex objects. When you\'27re finished using these objects, you can deallocate them using \b condition_free()\b0 and \b mutex_free()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macro \b condition_broadcast()\b0 wakes up all threads that are waiting (with \b condition_wait()\b0 ) for the condition \i c\i0 . This macro is similar to \b condition_signal()\b0 , except that \b condition_signal()\b0 doesn\'27t wake up every waiting thread.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 You must call one of these macros before freeing an object of type\b struct condition\b0 or \b struct mutex\b0 . See the discussion of \b condition_init()\b0 and \b mutex_init()\b0 for information on why you might want to use these types instead of \b condition_t\b0 and \b mutex_t\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macros \b condition_free()\b0 and \b mutex_free()\b0 let you deallocate condition and mutex objects that were allocated dynamically. Before deallocating such an object, you must guarantee that no other thread will reference it. In particular, a thread blocked in \b mutex_lock()\b0 or \b condition_wait()\b0 should be viewed as referencing the object continually; freeing the object out from under such a thread is erroneous, and can result in bugs that are extremely difficult to track down.\
\fs20 \
\fs28 \s26 \fs10 \
\fs28 \f0 \b \fs20 SEE ALSO \b0 \fs28 \f1 \b condition_alloc()\b0 , \b mutex_alloc()\b0 , \b condition_clear()\b0 , \b mutex_clear()\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macros \b condition_init()\b0 and \b mutex_init()\b0 initialize an object of the \b struct condition\b0 or \b struct mutex\b0 referent type, so that its address can be used wherever an object of type \b condition_t\b0 or \b mutex_t\b0 is expected. Initialization of the referent type is most often used when you have included the referent type itself (rather than a pointer) in a larger structure, for more efficient storage allocation.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For instance, a data structure might contain a component of type \b struct mutex\b0 to allow each instance of that structure to be locked independently. During initialization of the instance, you would call \b mutex_init()\b0 on the \b struct mutex\b0 component. The alternative of using a \b mutex_t\b0 component and initializing it using \b mutex_alloc()\b0 would be less efficient.\
\fs20 \
\fs28 If you\'27re going to free a condition or mutex object of type \b struct condition\b0 or \b struct mutex\b0 , you should first clear it using \b condition_clear()\b0 or \b mutex_clear()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 These macros let you associate a name with a condition or a mutex object. The name is used when trace information is displayed. You can also use this name for your own application-dependent purposes.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 /* Do something if this is a "TYPE 1" condition. */\
\fi0 if (strcmp(condition_name(c), "TYPE 1") == 0) \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macro \b condition_signal()\b0 should be called when one thread needs to indicate that the condition represented by the condition variable is now true. If any other threads are waiting (using \b condition_wait()\b0 ), at least one of them will be awakened. If no threads are waiting, nothing happens. The macro \b condition_broadcast()\b0 is similar to this one, except that it wakes up \i all\i0 threads that are waiting.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b condition_wait()\b0 unlocks the mutex it takes as a argument, suspends the calling thread until the specified condition is likely to be true, and locks the mutex again when the thread resumes. There\'27s no guarantee that the condition will be true when the thread resumes, so this function should always be used as follows:\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function provides the functionality of \b thread_abort()\b0 to C threads. The \b cthread_abort()\b0 function interrupts system calls; it\'27s usually used along with \b thread_suspend()\b0 , which stops a thread from executing any more user code. Calling \b cthread_abort()\b0 on a thread that isn\'27t suspended is risky, since it\'27s difficult to know exactly what system trap, if any, the thread might be executing and whether an interrupt return would cause the thread to do something useful.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 See \b thread_abort()\b0 for a full description of the use of this function.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function returns the number of threads that exist in the current task. You can use this function to help make sure that your task doesn\'27t create too many threads (over 200 or so). See \b cthread_set_limit()\b0 for information on restricting the number of threads in a task.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 printf("C thread count should be 1, is %d\\n", cthread_count());\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macros \b cthread_data()\b0 and \b cthread_set_data()\b0 let you associate arbitrary data with a thread, providing a simple form of thread-specific \'aaglobal\'ba variable. More elaborate mechanisms, such as per-thread property lists or hash tables, can then be built with these macros.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 int listen(any_t arg)\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_detach()\b0 is used to indicate that \b cthread_join()\b0 will never be called on the given thread. This is usually known at the time the thread is forked, so the most efficient usage is the following:\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Use the \b cthread_errno()\b0 function to get the errno value for the current thread. In the UNIX operating system, \b errno\b0 is a process-wide global variable that\'27s set to an error number when a UNIX system call fails. However, because Mach has multiple threads per process, Mach keeps errno information on a per-thread basis as well as in \b errno\b0 . \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Like the value of \b errno\b0 , the value returned by \b cthread_errno()\b0 is valid only if the last UNIX system call returned \f3 -\f1 1. Errno values are defined in the header file \b bsd/sys/errno.h\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_exit()\b0 terminates the calling thread. The result is passed to the thread that joins the caller, or is discarded if the caller is detached.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 An implicit \b cthread_exit()\b0 occurs when the top-level function of a thread returns, but it may also be called explicitly.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_fork()\b0 takes two arguments: a function for the new thread to execute, and an argument to this function. The \b cthread_fork()\b0 function creates a new thread of control in which the specified function is executed concurrently with the caller\'27s thread. This is the sole means of creating new threads.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b any_t\b0 type represents a pointer to any C type. The \b cthread_t\b0 type is an integer-size handle that uniquely identifies a thread of control. Values of type \b cthread_t\b0 will be referred to as thread identifiers. Arguments larger than a pointer must be passed by reference. Similarly, multiple arguments must be simulated by passing a pointer to a structure containing several components. The call to \b cthread_fork()\b0 returns a thread identifier that can be passed to \b cthread_join()\b0 or \b cthread_detach()\b0 . Every thread must be either joined or detached exactly once.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_join()\b0 suspends the caller until the specified thread \i t\i0 terminates. The caller receives either the result of \i t\i0 \'27s top-level function or the argument with which \i t\i0 explicitly called \b cthread_exit()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Attempting to join one\'27s own thread results in deadlock.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i limit\i0 : The new maximum number of C threads per task. Specify zero if you want no limit.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 These functions can help you to avoid creating too many threads. The danger in creating a large number of threads is that the kernel might run out of resources and panic. Usually, a task should avoid creating more than about 200 threads.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use \b cthread_set_limit()\b0 to set a limit on the number of threads in the current task. When the limit is reached, new C threads will appear to fork successfully. However, they will have no associated Mach thread, so they won\'27t do anything.\
\fs20 \
\fs28 Use \b cthread_limit()\b0 to find out how many threads can exist in the current task. If the returned value is zero (the default), then no limit is currently being enforced.\
\fs20 \
\fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important: \b0 \fs28 \f1 Use \b cthread_count()\b0 to determine when your task is approaching the maximum number of threads.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The functions \b cthread_name()\b0 and \b cthread_set_name()\b0 let you associate an arbitrary name with a thread. The name is used when trace information is displayed. The name may also be used for application-specific diagnostics.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 int listen(any_t arg)\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 These functions give C threads the functionality of \b thread_priority()\b0 and \b thread_max_priority()\b0 . See those functions for more details than are provided here.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b cthread_priority()\b0 function changes the base priority and (optionally) the maximum priority of \i t\i0 . If the new base priority is higher than the\i \i0 scheduled\i \i0 priority of the currently executing thread, this thread might be preempted. The maximum priority of the thread is also set if \i set_max\i0 is true. This call fails if \i priority\i0 is greater than the current maximum priority of the thread. As a result, \b cthread_priority()\b0 can lower\'d0but never raise\'d0the value of a thread\'27s maximum priority.\
\fs20 \
\fs28 The\b cthread_max_priority()\b0 function changes the maximum priority of the thread. Because it requires the privileged port for the processor set, this call can reset the maximum priority to any legal value. If the new maximum priority is less than the thread\'27s base priority, then the thread\'27s base priority is set to the new maximum priority.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i cthread\i0 is not a C thread, \i processor_set\i0 is not a privileged port for a processor set, or \i priority\i0 is out of range (not in 0-31).\
\fs20 \
\fs28 KERN_FAILURE: The requested operation would violate the thread\'27s maximum priority (only for \b cthread_priority()\b0 ) or the thread is not assigned to the processor set whose privileged port was presented.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_self()\b0 returns the caller\'27s own C-thread identifier, which is the same value that was returned by \b cthread_fork()\b0 to the creator of the thread. The C-thread identifier uniquely identifies the thread, and hence may be used as a key in data structures that associate user data with individual threads. Since thread identifiers may be reused by the underlying implementation, you should be careful to clean up such associations when threads exit.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 printf("This thread\'27s name is: %s\\n",\
\fi0 cthread_name(cthread_self()));\
\fi0 mutex_unlock(printing);\
\s26 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 SEE ALSO \b0 \fs28 \f1 \b cthread_fork()\b0 , \b cthread_thread()\b0 , \b thread_self()\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Use this function\i \i0 to set the errno value for the current thread to \i error\i0 . In the UNIX operating system, \b errno\b0 is a process-wide global variable that\'27s set to an error number when a UNIX system call fails. However, because Mach has multiple threads per process, Mach keeps errno information on a per-thread basis as well as in \b errno\b0 . This function has no effect on the value of \b errno\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The current thread\'27s errno value can be obtained by calling \b cthread_errno()\b0 . Errno values are defined in the header file \b bsd/sys/errno.h\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macro \b cthread_thread()\b0 returns the Mach thread that corresponds to the specified C thread \i t\i0 .\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 /* Save the cthread and thread values for the forked thread. */\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b cthread_yield()\b0 is a hint to the scheduler, suggesting that this would be a convenient point to schedule another thread to run on the current processor.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 int i, n;\
\fi0 \
\fi0 /* n is set previously */\
\fi0 for (i = 0; i < n; i += 1)\
\fi0 cthread_yield();\
\s26 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 SEE ALSO \b0 \fs28 \f1 \b cthread_priority()\b0 , \b thread_switch()\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The macro \b mutex_lock()\b0 attempts to lock the mutex \i m\i0 and blocks until it succeeds. If several threads attempt to lock the same mutex concurrently, one will succeed, and the others will block until \i m\i0 is unlocked. A deadlock occurs if a thread attempts to lock a mutex it has already locked.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 /* Only one thread at a time should call printf. */\
\fi0 mutex_lock(printing);\
\fi0 printf("Condition has been met\\n");\
\fi0 mutex_unlock(printing);\
\s26 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 SEE ALSO \b0 \fs28 \f1 \b mutex_try_lock()\b0 , \b mutex_unlock()\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b mutex_try_lock()\b0 attempts to lock the mutex \i m\i0 , like \b mutex_lock()\b0 , and returns true if it succeeds. If \i m\i0 is already locked, however, \b mutex_try_lock()\b0 immediately returns false rather than blocking. For example, a busy-waiting version of \b mutex_lock()\b0 could be written using \b mutex_try_lock()\b0 :\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i in\i0 : A message that was received on the exception port. This message structure should be at least 64 bytes long.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i out\i0 : An empty message to be filled by \b exc_server()\b0 and then sent. This message buffer should be at least 32 bytes long.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function calls the appropriate exception handler. You should call this function after you\'27ve received a message on an exception port that you set up previously. Usually, this function is used along with a user-defined exception handler, which must have the following protocol:\
\fs28 To receive a message on an exception port, you must first create a new port and make it the task or thread exception port. (You can\'27t use the default task exception port because you can\'27t get receive rights for it.) Before calling \b msg_receive()\b0 , you must set the \b local_port\b0 field of the header to the appropriate exception port and the \b msg_size\b0 field to the size of the structure for the incoming message.\
\fs20 \
\fs28 If it accepted the incoming message, \b exc_server()\b0 returns true; otherwise it returns false.\
\fs20 \
\fs28 You should keep a global value that indicates whether your exception handler successfully handled the exception. If it couldn\'27t, then you should forward the exception message to the old exception port.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i exception_port\i0 : The exception port of the affected thread. (If the thread doesn\'27t have its own exception port, then this should be the exception port of the task.)\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i clear_port\i0 : The port to which a reply message should be sent from the exception handler. If you don\'27t care to see the reply, you can use \b thread_reply()\b0 .\
\fs20 \
\fs28 \i thread\i0 : The thread in which the exception condition occurred. If the exception isn\'27t thread-specific, then specify THREAD_NULL.\
\fs20 \
\fs28 \i task\i0 : The task in which the exception condition occurred.\
\fs20 \
\fs28 \i exception\i0 : The type of exception that occurred; for example, EXC_SOFTWARE. Values for this variable are defined in the header file \b mach/exception.h\b0 .\
\fs20 \
\fs28 \i code\i0 : The exception code. The meaning of this code depends on the value of \i exception\i0 .\
\fs20 \
\fs28 \i subcode\i0 : The exception subcode. The meaning of this subcode depends on the values of \i exception\i0 and \i code\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function causes an exception message to be sent to \i exception_port\i0 , which results in a call to the exception handler. Usually this function is used along with a user-defined exception handler. (See \b exc_server()\b0 and \b mach_NeXT_exception()\b0 for more information on user-defined exception handlers.)\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can obtain \i exception_port\i0 by calling \b thread_get_exception_port()\b0 or (if no thread exception port exists or the exception affects the whole task) \b task_get_exception_port()\b0 .\
\fs20 \
\fs28 If you\'27re defining your own type of exception, you must have \i exception\i0 equal to EXC_SOFTWARE and \i code\i0 equal to or greater than 0x20000.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i host\i0 : The host for which information is to be obtained.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of statistics to be returned. Currently HOST_BASIC_INFO, HOST_PROCESSOR_SLOTS, and HOST_SCHED_INFO are implemented.\
\fs20 \
\fs28 \i host_info\i0 : Returns statistics about \i host\i0 .\
\fs20 \
\fs28 \i host_info_count\i0 : The number of integers in the info structure; returns the number of integers that Mach tried to fill the info structure with. For HOST_BASIC_INFO, you should set \i host_info_count\i0 to HOST_BASIC_INFO_COUNT. For HOST_PROCESSOR_SLOTS, you should set it to the maximum number of CPUs (returned by HOST_BASIC_INFO). For HOST_SCHED_INFO, set it to HOST_SCHED_INFO_COUNT.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns the selected information array for a host, as specified by \i flavor\i0 . The \i host_info\i0 argument is an array of integers that\'27s supplied by the caller and returned filled with specified information. The \i host_info_count\i0 argument is supplied by the caller as the maximum number of integers in \i host_info\i0 (which can be larger than the space required for the information). On return, it contains the actual number of integers in \i host_info\i0 . \
\fs20 \
\fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning: \b0 \fs28 \f1 This replaces the old \b host_info()\b0 call. It isn\'27t backwards compatible.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by HOST_BASIC_INFO. Its size is defined by HOST_BASIC_INFO_COUNT. Possible values of the \b cpu_type\b0 and \b cpu_subtype\b0 fields are defined in the header file \b mach/machine.h\b0 , which is included in \b mach/mach.h\b0 .\
\fs28 Processor slots of the active (available) processors are defined by HOST_PROCESSOR_SLOTS. The size of this information should be obtained from the \b max_cpus\b0 field of the structure returned by HOST_BASIC_INFO. HOST_PROCESSOR_SLOTS returns an array of integers, each of which is the slot number of a CPU.\
\fs20 \
\fs28 Additional information of interest to schedulers is defined by HOST_SCHED_INFO. The size of this information is defined by HOST_SCHED_INFO_COUNT.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i host\i0 is not a host, \i flavor\i0 is not recognized, or (for HOST_PROCESSOR_SLOTS) *\i count\i0 is less than \b max_cpus\b0 .\
\fs20 \
\fs28 KERN_FAILURE: *\i count\i0 is less than HOST_BASIC_INFO_COUNT (when \i flavor\i0 is HOST_BASIC_INFO) or HOST_SCHED_INFO_COUNT (for HOST_SCHED_INFO).\
\fs20 \
\fs28 MIG_ARRAY_TOO_LARGE: Returned info array is too large for \i host_info\i0 . The \i host_info\i0 argument is filled as much as possible, and \i host_info_count\i0 is set to the number of elements that would be returned if there were enough room.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function returns the version string compiled into \i host\i0 \'27s kernel\b \b0 at the time it was built. If you don\'27t use the \b kernel_version_t\b0 declaration, then you should allocate KERNEL_VERSION_MAX bytes for the version string.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t ret;\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function returns send rights to the privileged port for the specified processor set. This port is used in calls that can affect other threads or tasks. For example, \b processor_set_tasks()\b0 requires the privileged port because it returns the port of every task on the system. \
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t error;\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i host_priv\i0 was not a privileged host port, or \i processor_set_name\i0 didn\'27t name a valid processor set.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i host\i0 : The host port for the desired host. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i processor_set_list\i0 : Returns an array of processor sets currently existing on \i host\i0 ; no particular ordering is guaranteed.\
\fs20 \
\fs28 \i processor_set_ count\i0 : Returns the number of processor sets in the \i processor_set_list\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function returns send rights to the name port for each processor set currently assigned to \i host\i0 . The \b host_processor_set_priv()\b0 function can be used to obtain the privileged ports from these if desired. The \i processor_set_list\i0 argument is an array that is created as a result of this call. You should call \b vm_deallocate()\b0 on this array when the data is no longer needed. \
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 In single-processor systems, you can get the same information by calling \b processor_set_default()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 \b host_processors()\b0 gets send rights to the processor port for each processor existing on \i host_priv\i0 . The \i processor_list\i0 argument is an array that is created as a result of this call. The caller may wish to call \b vm_deallocate()\b0 on this array when the data is no longer needed. \
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t error;\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The \b host_self()\b0 function returns send rights to the host port for the host on which the call is executed. This port can be used only to obtain information about the host, not to control the host.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b host_priv_self()\b0 function returns send rights to the privileged host port for the host on which the call is executed. This port is used to control physical resources on that host and is only available to privileged tasks. PORT_NULL is returned if the invoker is not the UNIX superuser.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b mach_error()\b0 displays a message on \b stderr\b0 . The message contains the string specified by \i string\i0 , the string returned by \b mach_error_string()\b0 , and the actual error value (\i error\i0 ). Since\b mach_error()\b0 isn\'27t thread-safe, you might want to protect it with a mutex if you call it in a multiple-thread task.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b mach_error_string()\b0 returns the string associated with \i error\i0 .\
\fs20 \
\fs28 Note that because the error value specified by \i error\i0 is of type \b kern_return_t\b0 , these functions work only with Mach functions.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b mach_NeXT_exception()\b0 displays a message on \b stderr\b0 . The message contains the string specified by \i string\i0 , then the string returned by \b mach_NeXT_exception_string()\b0 , and then the values of \i exception\i0 , \i code\i0 , and \i subcode\i0 . Since\b mach_NeXT_exception()\b0 isn\'27t thread-safe, you might want to protect it with a mutex if you call it in a multiple-thread task.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b mach_NeXT_exception_string()\b0 returns the string associated with \i exception\i0 , \i code\i0 , and \i subcode\i0 .\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i fd\i0 : An open UNIX file descriptor for the file that\'27s to be mapped.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i offset\i0 : The byte offset within the file, at which mapping is to begin.\
\fs20 \
\fs28 \i address\i0 : A pointer to an address in the calling process at which the mapped file should start. This address, unlike the offset, must be page-aligned.\
\fs20 \
\fs28 \i find_space\i0 : If true, the kernel will select an unused address range at which to map the file and return its value in \i address\i0 .\
\fs20 \
\fs28 \i size\i0 : The number of bytes to be mapped.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b map_fd()\b0 is a UNIX extension that\'27s technically not part of Mach. This function causes \i size\i0 bytes of data starting at \i offset\i0 in the file specified by \i fd\i0 to be mapped into the virtual memory at the address specified by \i address. \i0 If \i find_space\i0 is true, the input value of \i address\i0 can be null, and the kernel will find an unused piece of virtual memory to use. (You should free this space with \b vm_deallocate()\b0 when you no longer need it.) If you provide a value for \i address\i0 , it must be page-aligned and at least \i size\i0 bytes long. The sum of \i offset\i0 and \i size\i0 must not exceed the length of the file.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Memory mapping doesn\'27t cause I/O to take place. When specific pages are first referenced, they cause page faults that bring in the data. The mapped memory is copy-on-write. Modified data is returned to the file only by a \b write()\b0 call.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i header\i0 : The address of a buffer in which the message is to be received. Two fields of the message header must be set before the call is made: \b msg_local_port\b0 must be set to the value of the port from which the message is to be received, and \b msg_size\b0 must be set to the maximum size of the message that may be received. This maximum size must be less than or equal to the size of the buffer.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 : The failure conditions under which \b msg_receive()\b0 should terminate. The value of this argument is a combination (using the bitwise OR operator) of the following options. Unless one of these values is explicitly specified, \b msg_receive()\b0 does not return until a message has been received.\
\fs20 \
\fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 RCV_TIMEOUT: Specifies that \b msg_receive()\b0 should return when the specified timeout elapses if a message has not arrived by that time; if not specified, the timeout will be ignored (that is, it will be infinite).\
\fs20 \
\fs28 RCV_INTERRUPT: Specifies that \b msg_receive()\b0 should return when a software interrupt occurs in this thread.\
\fs20 \
\fs28 RCV_LARGE: Specifies that \b msg_receive()\b0 should return without dequeuing a message if the next message in the queue is larger than \i header\b \i0 .msg_size\b0 . (Normally, a message that is too large is dequeued and lost.) You can use this option to dynamically determine how large your message buffer must be.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use MSG_OPTION_NONE to specify that none of the above options is desired.\
\fs20 \
\fs28 \i timeout\i0 : If RCV_TIMEOUT is specified in \i option\i0 , then \i timeout\i0 is the maximum time in milliseconds to wait for a message before giving up.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b msg_receive()\b0 retrieves the next message from the port or port set specified in the \b msg_local_port\b0 field of \i header\i0 . If a port is specified, the port must\i \i0 not be a member of a port set. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If a port set is specified, then \b msg_receive()\b0 will retrieve messages sent to any of the set\'27s member ports. Mach sets the \b msg_local_port\b0 field to the specific port on which the message was found. It\'27s not an error for the port set to have no members, or for members to be added and removed from a port set while a \b msg_receive()\b0 on the port set is in progress. \
\fs20 \
\fs28 The message consists of its header, followed by a variable amount of data; the message header supplied to \b msg_receive()\b0 must specify (in \b msg_size\b0 ) the maximum size of the message that can be received into the buffer provided.\
\fs20 \
\fs28 If no messages are present on the port(s) in question, \b msg_receive()\b0 will wait until a message arrives, or until one of the specified termination conditions is met (see the description of the \i option\i0 argument for this function).\
\fs20 \
\fs28 If the message is successfully received, then \b msg_receive()\b0 sets the \b msg_size\b0 field of the header to the size of the received message. If the RCV_LARGE option was set and \b msg_receive()\b0 returned RCV_TOO_LARGE, then the \b msg_size\b0 field is set to the size of the message that was too large.\
\fs20 \
\fs28 If the received message contains out-of-line data (that is, data for which the \b msg_type_inline\b0 attribute was specified as false), the data will be returned in a newly allocated region of memory; the message body will contain a pointer to that new region. You should deallocate this memory when the data is no longer needed. See the \b vm_allocate()\b0 call for a description of the state of newly allocated memory.\
\fs20 \
\fs28 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 RCV_SUCCESS: The message has been received.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 RCV_INVALID_MEMORY: The message specified was not writable by the calling task.\
\fs20 \
\fs28 RCV_INVALID_PORT: An attempt was made to receive on a port to which the calling task does not have the proper access, or which was deallocated (see \b port_deallocate()\b0 ) while waiting for a message.\
\fs20 \
\fs28 RCV_TOO_LARGE: The message header and body combined are larger than the size specified by \b msg_size\b0 . Unless the RCV_LARGE option was set, the message has been dequeued and lost. If the RCV_LARGE option was specified, then Mach sets \b msg_size\b0 to the size of the message that was too large and leaves the message at the head of the queue.\
\fs20 \
\fs28 RCV_NOT_ENOUGH_MEMORY: The message to be received contains more out-of-line data than can be allocated in the receiving task.\
\fs20 \
\fs28 RCV_TIMED_OUT: The message was not received after \i timeout\i0 milliseconds.\
\fs20 \
\fs28 RCV_INTERRUPTED: A software interrupt occurred and the RCV_INTERRUPT option was specified.\
\fs20 \
\fs28 RCV_PORT_CHANGE: The port specified was added to a port set during the duration of the \b msg_receive()\b0 call.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i header\i0 : Address of a message buffer that will be used for both \b msg_send()\b0 and \b msg_receive()\b0 . This buffer contains a message header followed by the data for the message to be sent. The \b msg_remote_port \b0 field specifies the port to which the message is to be sent. The \b msg_local_port\b0 field specifies the port on which a message is then to be received; if this port is the special value PORT_DEFAULT, it gets replaced by the value PORT_NULL for the purposes of the \b msg_send()\b0 operation.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 : A union of the \i option\i0 arguments for the send and receive (see \b msg_send()\b0 and \b msg_receive()\b0 ).\
\fs20 \
\fs28 \i rcv_size\i0 : The maximum size allowed for the received message; this must be less than or equal to the size of the message buffer. The \b msg_size\b0 field in the header specifies the size of the message to be sent.\
\fs20 \
\fs28 \i send_timeout\i0 ,\i rcv_timeout\i0 : The timeout values to be applied to the component operations. These are used only if the option SEND_TIMEOUT or RCV_TIMEOUT is specified.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b msg_rpc()\b0 is a hybrid call that performs a \b msg_send()\b0 followed by a \b msg_receive()\b0 , using the same message buffer. Because of the order of the send and receive, this function is appropriate for clients of Mach servers. However, the \b msg_rpc()\b0 call to a Mach server is usually performed by MiG-generated code, not by handwritten code.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 RPC_SUCCESS: The message was successfully sent and a reply was received.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Other possible values are the same as those for \b msg_send()\b0 and \b msg_receive()\b0 ; any error during the \b msg_send()\b0 portion will terminate the call.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i header\i0 : The address of the message to be sent. A message consists of a fixed-size header followed by a variable number of data descriptors and data items. See the header file \b mach/message.h\b0 for a definition of the message structure. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 : The failure conditions under which \b msg_send()\b0 should terminate. The value of this argument is a combination (using the bitwise OR operator) of the following options. Unless one of these values is explicitly specified, \b msg_send()\b0 does not return until the message is successfully queued for the intended receiver.\
\fs20 \
\fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 SEND_TIMEOUT: Specifies that the \b msg_send()\b0 request should terminate after the timeout period has elapsed, even if the kernel has been unable to queue the message.\
\fs20 \
\fs28 SEND_NOTIFY: Allows the sender to send exactly one message\i \i0 without being suspended even if the destination port is full. When that message can be posted to the receiving port queue, this task receives a message that notifies it that another message can be sent. If the sender tries to send a second message with this option to the same port before the first notification arrives, the result is an error. If both SEND_NOTIFY and SEND_TIMEOUT are specified, \b msg_send()\b0 will wait until the specified timeout has elapsed before invoking the SEND_NOTIFY option.\
\fs20 \
\fs28 SEND_INTERRUPT: Specifies that \b msg_send()\b0 should return if a software interrupt occurs in this thread.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use MSG_OPTION_NONE to specify that none of the above options is wanted.\
\fs20 \
\fs28 \i timeout\i0 : If the destination port is full and the SEND_TIMEOUT option has been specified, this value specifies the maximum wait time (in milliseconds).\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b msg_send()\b0 transmits a message from the current task to the port specified in the message header field. The message consists of its header, followed by a variable number of data descriptors and data items.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If the \b msg_local_port\b0 field isn\'27t set to PORT_NULL, send rights to that port will be passed to the receiver of this message. The receiver task can use that port to send a reply to this message.\
\fs20 \
\fs28 If the SEND_NOTIFY option is used and this call returns a SEND_WILL_NOTIFY code, you can expect to receive a notify message from the kernel. This message will be either a NOTIFY_MSG_ACCEPTED or a NOTIFY_PORT_DELETED message, depending on what happened to the queued message. The \b notify_port\b0 field\i \i0 in these messages is the port to which the original message was sent. The formats for these messages are defined in the header file \b sys/notify.h\b0 .\
\fs20 \
\fs28 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 /* From the handwritten part of a Mach server... */\
\fi0 while (TRUE)\
\fi0 \{ \
\fi0 /* Receive a request from a client. */\
\fi0 msg.head.msg_local_port = port;\
\fi0 msg.head.msg_size = sizeof(struct message);\
\fi0 ret = msg_receive(&msg.head, MSG_OPTION_NONE, 0);\
\fi0 if (ret != RCV_SUCCESS) /* ignore errors */; \
\fi0 \
\fi0 /* Feed the request into the server. */\
\fi0 (void)add_server(&msg, &reply);\
\fi0 \
\fi0 /* Send a reply to the client. */\
\fi0 reply.head.msg_local_port = port;\
\fi0 ret = msg_send(&reply.head, MSG_OPTION_NONE, 0);\
\fi0 if (ret != SEND_SUCCESS) /* ignore errors */; \
\fi0 \}\
\s25 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 SEND_SUCCESS: The message has been queued for the destination port.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 SEND_INVALID_MEMORY: The message header or body was not readable by the calling task, or the message body specified out-of-line data that was not readable.\
\fs20 \
\fs28 SEND_INVALID_PORT: The message refers either to a port for which the current task does not have access, or to which access was explicitly removed from the current task (see \b port_deallocate()\b0 ) while waiting for the message to be posted, or a \b msg_type_name\b0 field in the message specifies rights that the name doesn\'27t denote in the task (for example, specifying MSG_TYPE_SEND and supplying a port set name).\
\fs20 \
\fs28 SEND_TIMED_OUT: The message was not sent since the destination port was still full after \i timeout\i0 milliseconds.\
\fs20 \
\fs28 SEND_WILL_NOTIFY: The destination port was full but the SEND_NOTIFY option was specified. A notification message will be sent when the message can be posted.\
\fs20 \
\fs28 SEND_NOTIFY_IN_PROGRESS: The SEND_NOTIFY option was specified but a notification request is already outstanding for this thread and given destination port.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task in which the new port is created (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : Returns the name used by \i task\i0 for the new port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_allocate()\b0 causes a port to be created for the specified task; the resulting port is returned in\i port_name. \i0 The target task initially has both send and receive rights to the port. The new port isn\'27t a member of any port set.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task that wants to relinquish rights to the port (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : The name that \i task\i0 uses for the port to be deallocated.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_deallocate()\b0 requests that the target task\'27s access to a port be relinquished.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If \i task\i0 has receive rights for the port and the port doesn\'27t have a backup port, these things happen:\
\fs20 \
\fs28 \s8 \li2494 \fi-378 \'b7 The port is destroyed.\
\'b7 All other tasks with send access to the port are notified of its destruction.\
\'b7 If the port is a member of a port set, it\'27s removed from the port set.\
\s4 \li2116 \fi0 \fs20 \
\fs28 If \i task\i0 has receive rights for the port and the port \i does\i0 have a backup port, then the following things happen:\
\fs20 \
\fs28 \s6 \li2494 \fi-378 \'b7 If the port is a member of a port set, it\'27s removed from the port set.\
\fs20 \
\fs28 \'b7 Send and receive rights for the port are sent to the backup port in a notification message (see \b port_set_backup()\b0 ).\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The functions \b port_extract_receive()\b0 and \b port_extract_send()\b0 remove the port access rights that \i task\i0 has for a port and return the rights to the caller. This leaves \i task\i0 with no rights for the port.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b port_extract_send()\b0 function extracts send rights; \i task\i0 can\'27t have receive rights for the named port. The \b port_extract_receive()\b0 \i \i0 function extracts receive rights.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i task\i0 was invalid or \i its_name\i0 doesn\'27t name a port for which \i task\i0 has the required rights.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The functions \b port_insert_receive()\b0 and \b port_insert_send()\b0 give a task rights with a specific name. If \i task\i0 already has rights named \i its_name\i0 , or has some other name for \i my_port\i0 , the operation will fail. The \i its_name\i0 argument can\'27t be a predefined port, such as PORT_NULL.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b port_insert_send()\b0 function inserts send rights, and \b port_insert_receive()\b0 inserts receive rights.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task whose port name space is queried.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_names\i0 : Returns the names of the ports and port sets in the port name space of \i task\i0 , in no particular order. \
\fs20 \
\fs28 \i port_names_count\i0 : Returns the number of names returned.\
\fs20 \
\fs28 \i port_types\i0 : Returns the type of each corresponding name. This indicates what kind of rights the task holds for the port, or whether the name refers to a port set. The type is one of the following: PORT_TYPE_SEND (send rights only), PORT_TYPE_RECEIVE_OWN (send and receive rights), PORT_TYPE_SET (the port is a port set).\
\fs20 \
\fs28 \i port_types_count\i0 : Returns the same value as \i port_names_count\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_names()\b0 returns information about the port name space of \i task\i0 . It returns the port and port set names that are currently valid for \i task\i0 . For each name, it also returns what type of rights \i task\i0 holds.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i port_names\i0 and \i port_types\i0 arguments are arrays that are automatically allocated when the reply message is received. You should use \b vm_deallocate()\b0 on them when the data is no longer needed. \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_rename()\b0 changes the name by which a port or port set is known to \i task. \i0 The port name specified in \i new_name\i0 must not already be in use, and it can\'27t be a predefined port, such as PORT_NULL. Currently, a name is a small integer.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 One way to guarantee that a name isn\'27t already in use is to deallocate a port and then use its name as \i new_name\i0 . Another way is to check all the existing names, using \b port_names()\b0 , before you call \b port_rename()\b0 . If you choose another naming scheme, you should be prepared to try another name if \b port_rename()\b0 returns a KERN_NAME_EXISTS error. \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NAME_EXISTS: \i task\i0 already has a port or port set\i \i0 named \i new_name.\
\fs20 \
\fs28 \i0 KERN_INVALID_ARGUMENT: \i task\i0 was invalid, or \i task\i0 didn\'27t know any ports or port sets named \i old_name\i0 , or \i new_name\i0 was an invalid name.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_add()\b0 moves the named port into the named port set. The \i task\i0 must have receive rights for the port. If the port is already a member of another port set, it\'27s removed from that set first.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t error;\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NOT_RECEIVER: \i task \i0 doesn\'27t have receive rights for the port\i .\
\fs20 \
\fs28 \i0 KERN_INVALID_ARGUMENT: \i task\i0 was invalid, or \i set_name\i0 doesn\'27t name a valid port set, or \i port_name\i0 doesn\'27t name a valid port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_allocate()\b0 causes a port set to be created for the specified task; the resulting set\'27s name is returned in \i set_name. \i0 The new port set is empty.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t error;\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task that has receive rights for the named port (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : \i task\i0 \'27s name for the port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_backlog()\b0 changes the backlog value on the specified port (the port\'27s backlog value is the number of unreceived messages that are allowed in its message queue before the kernel will refuse to accept any more sends to that port). \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The task specified by \i task\i0 must have receive rights for the named port.\
\fs20 \
\fs28 The maximum backlog value is the constant PORT_BACKLOG_MAX. You can get a port\'27s current backlog value by calling \b port_status()\b0 . \
\fi0 mach_error("Call to port_set_backlog failed", error);\
\s25 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The backlog value has been changed.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NOT_RECEIVER: \i task \i0 doesn\'27t have receive rights for the port.\
\fs20 \
\fs28 KERN_INVALID_ARGUMENT: \i task\i0 was invalid, or \i port_name\i0 doesn\'27t name a valid port, or the desired backlog wasn\'27t greater than 0, or the desired backlog was greater than PORT_BACKLOG_MAX.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task that has receive rights for the named port (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : \i task\i0 \'27s name for the port right.\
\fs20 \
\fs28 \i backup\i0 : The new backup port. If you want to disable the current backup port without setting a new one, set this to PORT_NULL.\
\fs20 \
\fs28 \i previous\i0 : Returns the previous backup port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Use this function to keep a port alive despite its being deallocated by its receiver. If the call to \b port_set_backup()\b0 is successful, then whenever \i port_name\i0 is deallocated by its receiver, \i backup\i0 will receive a notification message with receive and send rights for\i port_name\i0 . As far as \i task\i0 is concerned, the port will be deleted; however, as far as senders to the port are concerned, the port will continue to exist.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 To let a port die naturally after its backup port has been set, call \b port_set_backup()\b0 on it with \i backup\i0 set to PORT_NULL. \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_deallocate()\b0 requests that the port set of \i task \i0 be destroyed. If the port set isn\'27t empty, any members are first removed.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 kern_return_t error;\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i task\i0 was invalid or \i set_name\i0 doesn\'27t name a valid port set.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_remove()\b0 removes the named port from a port set. The \i task\i0 must have receive rights for the port, and the port must be a member of a port set.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 error=port_set_remove(task_self(), my_port);\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_set_status()\b0 returns a list of the ports in a port set. The \i members\i0 argument is an array that\'27s automatically allocated when the reply message is received. You should use \b vm_deallocate()\b0 on it when the data is no longer needed.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i task\i0 was invalid or \i set_name\i0 doesn\'27t name a valid port set.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task that has receive rights for the port in question (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : \i task\i0 \'27s name for the port right.\
\fs20 \
\fs28 \i port_set_name\i0 : Returns \i task\i0 \'27s name for the port set that the named port belongs to, or PORT_NULL if it isn\'27t in a set. \
\fs20 \
\fs28 \i num_msgs\i0 : Returns the number of messages queued on this port. If \i task\i0 isn\'27t the port\'27s receiver, the number of messages will be returned as negative.\
\fs20 \
\fs28 \i backlog\i0 : Returns the number of messages that can be queued to this port without causing the sender to block.\
\fs20 \
\fs28 \i owner\i0 : Returns the same value as \i receiver\i0 , since ownership rights and receive rights aren\'27t separable.\
\fs20 \
\fs28 \i receiver\i0 : Returns true if \i task\i0 has receive rights to \i port_name\i0 ; otherwise, returns false.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i task\i0 : The task whose port name space is queried.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : The name being queried. \
\fs20 \
\fs28 \i port_type\i0 : Returns a value that indicates what kind of rights the task holds for the port, or whether the name refers to a port set. This value is one of the following: PORT_TYPE_SEND (send rights only), PORT_TYPE_RECEIVE_OWN (send and receive rights), PORT_TYPE_SET (the port is a port set).\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b port_type()\b0 returns information about \i task\'27\i0 s rights for a specific name in its port name space.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i task\i0 was invalid or \i task\i0 didn\'27t have any rights named \i port_name\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 \b processor_assign()\b0 changes the processor set to which \i processor\i0 is assigned. \b processor_control()\b0 returns information about \i processor\i0 . \b processor_exit()\b0 shuts down \i processor\i0 . \b processor_get_assignment()\b0 returns the processor set to which \i processor\i0 is assigned. \b processor_start()\b0 starts up \i processor\i0 .\
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 These functions are useful only on multiprocessor systems. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i processor\i0 : The processor for which information is to be obtained.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of information that is wanted. Currently only PROCESSOR_BASIC_INFO is implemented.\
\fs20 \
\fs28 \i host\i0 : Returns the non-privileged host port for the host on which the processor resides.\
\fs20 \
\fs28 \i processor_info\i0 : Returns information about the processor specified by \i processor\i0 .\
\fs20 \
\fs28 \i processor_info_count\i0 : Size of the info structure. Should be PROCESSOR_BASIC_INFO_COUNT when \i flavor\i0 is PROCESSOR_BASIC_INFO.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns the selected information array for a processor, as specified by \i flavor\i0 . The \i processor_info\i0 argument is an array of integers that is supplied by the caller and filled with specified information. The \i processor_info_count\i0 argument is supplied as the maximum number of integers in \i processor_info\i0 . On return, it contains the actual number of integers in \i processor_info\i0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by PROCESSOR_BASIC_INFO. The size of this information is defined by PROCESSOR_BASIC_INFO_COUNT. The data structures used by PROCESSOR_BASIC_INFO are defined in the header file \b mach/processor_info.h\b0 . Possible values of the \b cpu_type\b0 and \b cpu_subtype\b0 fields are defined in the header file \b mach/machine.h\b0 .\
\fs20 \
\fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 typedef int *processor_info_t; /* variable length array of int */\
\fi0 \
\fi0 /* one interpretation of info is */\
\fi0 struct processor_basic_info \{\
\fi0 cpu_type_t cpu_type; /* cpu type */\
\fi0 cpu_subtype_t cpu_subtype; /* cpu subtype */\
\fi0 boolean_t running; /* is processor running? */\
\fi0 int slot_num; /* slot number */\
\fi0 boolean_t is_master; /* is this the master processor */\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i processor\i0 isn\'27t a known processor. \
\fs20 \
\fs28 MIG_ARRAY_TOO_LARGE: Returned info array is too large for \i processor_info\i0 . The \i processor_info\i0 argument is filled as much as possible, and \i processor_info_count\i0 is set to the number of elements that would be returned if there were enough room. \
\fs20 \
\fs28 KERN_FAILURE: \i flavor\i0 isn\'27t recognized or \i processor_info_count\i0 is too small.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i host\i0 : The host whose default processor set is requested.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i default_set\i0 : Returns the name (nonprivileged) port for the default processor set.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The default processor set is used by all threads, tasks, and processors that aren\'27t explicitly assigned to other sets. This function returns a port that can be used to obtain information about this set (for example, how many threads are assigned to it). This port isn\'27t privileged and thus can\'27t be used to perform operations on that set; call \b host_processor_set_priv()\b0 after \b processor_set_default()\b0 to get the privileged port.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 error=processor_set_default(host_self(), &default_set);\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function destroys \i processor_set\i0 , reassigning all of its tasks, threads, and processors to the default processor set.\
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 This function is useful only on multiprocessor systems. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i processor_set\i0 : The processor set for which information is to be obtained.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of information that is wanted. Should be PROCESSOR_SET_BASIC_INFO or PROCESSOR_SET_SCHED_INFO.\
\fs20 \
\fs28 \i host\i0 : Returns the nonprivileged host port for the host on which the processor set resides.\
\fs20 \
\fs28 \i processor_set_info\i0 : Returns information about the processor set specified by \i processor_set\i0 . \
\fs20 \
\fs28 \i processor_set_info_count\i0 : Size of the info structure. Should be PROCESSOR_SET_BASIC_INFO_COUNT when \i flavor\i0 is PROCESSOR_SET_BASIC_INFO, and PROCESSOR_SET_SCHED_INFO_COUNT when \i flavor\i0 is PROCESSOR_SET_SCHED_INFO.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns the selected information array for a processor set, as specified by \i flavor\i0 . The \i processor_set_info\i0 argument is an array of integers that is supplied by the caller, and filled with specified information. The \i processor_set_info_count\i0 argument is supplied as the maximum number of integers in \i processor_set_info\i0 . On return, it contains the actual number of integers in \i processor_set_info\i0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by PROCESSOR_SET_BASIC_INFO. The size of this information is defined by PROCESSOR_SET_BASIC_INFO_COUNT. The \b load_average\b0 and \b mach_factor\b0 fields are scaled by the constant LOAD_SCALE (that is, the integer value returned is the load average or Mach factor multiplied by LOAD_SCALE). \
\fs20 \
\fs28 The \i Mach factor\i0 , like the UNIX load average, is a measurement of how busy the system is. Unlike the load average, higher Mach factors mean that the system is less busy. The Mach factor tells you how much of a CPU you have available for running an application. For example, on a single-processor system with one job running, the Mach factor is 0.5; this means if another job starts running it will get half of the CPU. (Two jobs will be running, each getting half the CPU.) On a single-processor system, the Mach factor is between zero and one. On a multiprocessor system, the Mach factor can go over one. For example, a three-processor system with one job running has a Mach factor of 2.0, since two processors are available to new jobs.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i processor_set\i0 is not a processor set, or \i flavor\i0 is not recognized.\
\fs20 \
\fs28 KERN_FAILURE: \i processor_set_info_count\i0 is less than what it should be.\
\fs20 \
\fs28 MIG_ARRAY_TOO_LARGE: Returned info array is too large for \i processor_set_info\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function affects only newly created or newly assigned threads unless you specify \i change_threads\i0 as true.\
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 This function is useful only on multiprocessor systems. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i processor_set\i0 : The processor set whose allowed policies are to be changed. This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i policy\i0 : The policy to enable or disable. Currently, the only valid policies are POLICY_TIMESHARE, POLICY_INTERACTIVE, and POLICY_FIXEDPRI. You can\'27t disable timesharing.\
\fs20 \
\fs28 \i change_threads\i0 : Specify true if you want to reset to timesharing the policies of any threads with the newly disallowed policy. Otherwise, specify false.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Processor sets may restrict the scheduling policies to be used for threads assigned to them. These two calls provide the mechanism for designating permitted and forbidden policies. The current set of permitted policies can be obtained from \b processor_set_info()\b0 . Timesharing can\'27t be forbidden by any processor set. This is a compromise to reduce the complexity of the assign operation; any thread whose policy is forbidden by the target processor set has its policy reset to timesharing. If the \i change_threads\i0 argument to \b processor_set_policy_disable()\b0 is true, threads currently assigned to this processor set and using the newly disabled policy will have their policy reset to timesharing.\
\fs20 \
\fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning: \b0 \fs28 \f1 Don\'27t use POLICY_FIXEDPRI unless you\'27re familiar with the consequences of fixed-priority scheduling. Using fixed-priority scheduling in a process can keep other processes from getting any CPU time. If processes that are essential to the functioning of the system don\'27t get CPU time, you might have to reboot your system to make it work normally.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i processor_set\i0 isn\'27t the privileged port of a processor set, \i policy\i0 isn\'27t a valid policy, or an attempt was made to disable timesharing.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i processor_set\i0 : The processor set to be affected. This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i task_list\i0 : Returns the set of tasks currently assigned to \i processor_set\i0 ; no particular ordering is guaranteed.\
\fs20 \
\fs28 \i task_count\i0 : Returns the number of tasks in \i task_list\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function gets send rights to the kernel port for each task currently assigned to \i processor_set\i0 . The \i task_list\i0 argument is an array that is created as a result of this call. You should call \b vm_deallocate()\b0 on this array when you no longer need the data.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 task_array_t task_list;\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i processor_set\i0 : The processor set to be affected. This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i thread_list\i0 : Returns the set of threads currently assigned to \i processor_set\i0 ; no particular ordering is guaranteed.\
\fs20 \
\fs28 \i thread_count\i0 : Returns the number of threads in \i thread_list\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function gets send rights to the kernel port for each thread currently assigned to \i processor_set\i0 . The \i thread_list\i0 argument is an array that is created as a result of this call. You should call \b vm_deallocate()\b0 on \i thread_list\i0 when you no longer need the data.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 thread_array_t thread_list;\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns the task port for another process, named by its process ID, on the same host as \i task\i0 . This call succeeds only if the caller is the superuser or \i task\i0 has the same user ID as the process specified by \i pid\i0 . If the call fails, \i result_task\i0 is set to TASK_NULL.\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 pid=fork();\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE: \i target_task\i0 has a different user ID from the process corresponding to \i pid,\i0 and the caller\i \i0 isn\'27t the superuser; or \i pid\i0 didn\'27t refer to a valid process; or \i target_task\i0 wasn\'27t a valid task.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i parent_task\i0 : The task from which the child\'27s capabilities are drawn.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i inherit_memory\i0 : If set, the address space of the child task is built from the parent task according to its memory inheritance values; otherwise, the child task is given an empty address space.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_create()\b0 creates a new task from \i parent_task\i0 ; the resulting task (\i child_task\i0 ) acquires shared or copied parts of the parent\'27s address space (see \b vm_inherit()\b0 ). The child task initially has no threads; you put threads in it using \b thread_create()\b0 . \
\fs20 \
\fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important: \b0 \fs28 \f1 Normally, you should use the UNIX \b fork()\b0 system call instead of \b task_create()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The child task gets the four special ports initialized for it at task creation. The kernel port (task port) is created, and send rights for it are given to the child and returned to the caller in \i child_task\i0 . The notify port is initialized to null. The child inherits its bootstrap and exception ports from the parent task. The new task can get send rights to these ports with the call \b task_get_special_port()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_get_special_port()\b0 returns send rights to one of a set of special ports for the task specified by \i task. \i0 In the case of the task\'27s own notify port, the task also gets receive rights.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b task_set_special_port()\b0 sets one of a set of special ports for the task specified by \i task\i0 .\
\fs20 \
\fs28 The function \b task_self()\b0 returns the port to which kernel calls for the currently executing thread should be directed. Currently, \b task_self()\b0 returns the task kernel port, which is a port for which the kernel has receive rights and which it uses to identify a task. In the future it may be possible for one task to interpose a port as another task\'27s kernel port. At that time \b task_self()\b0 will still return the port to which the executing thread should direct kernel calls, but it may no longer be a port for which the kernel has receive rights.\
\fs20 \
\fs28 If a controller task has send access to the kernel port of a subject task, then the controller task can perform kernel operations for the subject task. Normally, only the task itself and the task that created it will have access to the task kernel port, but any task may pass rights to its kernel port to any other task.\
\fs20 \
\fs28 The function \b task_notify()\b0 returns receive and send rights to the notify port associated with the task to which the executing thread belongs. The notify port is a port on which the task should receive notification of such kernel events as the destruction of a port to which it has send rights.\
\fs20 \
\fs28 The other special ports associated with a task are the bootstrap port and the exception port. The bootstrap port is a port to which a thread may send a message requesting other system service ports. This port isn\'27t used by the kernel. The task\'27s exception port is the port to which messages are sent by the kernel when an exception occurs and the thread causing the exception has no exception port of its own.\
\fs20 \
\fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important: \b0 \fs28 \f1 If you set your task\'27s bootstrap port, you should also set the global variable \b bootstrap_port\b0 to \i special_port\i0 . The \b bootstrap_port\b0 variable is task-wide and is used by \b mach_init\b0 and other processes to determine your task\'27s bootstrap port. Since you can\'27t change the value of the \b bootstrap_port\b0 variable in another task, you should use care when changing the bootstrap port of another task. \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The port was returned or set.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: Either \i task\i0 is not a task or \i which_port\i0 is an invalid port selector.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task to be affected (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of statistics that are wanted. Currently only TASK_BASIC_INFO is implemented.\
\fs20 \
\fs28 \i task_info\i0 : Returns statistics about \i target_task\i0 .\
\fs20 \
\fs28 \i task_info_count\i0 : Size of the info structure. Currently this must be TASK_BASIC_INFO_COUNT.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_info()\b0 returns the information specified by \i flavor\i0 about a task\i . \i0 The \i task_info\i0 argument is an array of integers that\'27s supplied by the caller and returned filled with information. The \i task_info_count\i0 argument is supplied as the maximum number of integers in \i task_info. \i0 On return, it contains the actual number of integers in \i task_info\i0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Currently there\'27s only one flavor of information, defined by TASK_BASIC_INFO. Its size is defined by TASK_BASIC_INFO_COUNT. The definition of the information structure returned by TASK_BASIC_INFO is:\
\fs28 MIG_ARRAY_TOO_LARGE: The returned info array is too large for \i task_info\i0 . The \i task_info\i0 argument is filled as much as possible, and \i task_info_count\i0 is set to the number of elements that would be returned if there were enough room.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The priority of a task is used only for creation of new threads; the priority of a new thread priority is set to that of its task. The \b task_priority()\b0 function changes this task priority. It also sets the priorities of all threads in the task to this new priority if \i change_threads\i0 is true. Existing threads are not affected otherwise. If this priority change violates the maximum priority of some threads, as many threads as possible will be changed and an error code will be returned.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Priorities range from 0 to 31, where higher numbers denote higher priorities. You can retrieve the current scheduling priority using \b thread_info()\b0 .\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i task\i0 is not a task, or \i priority\i0 is not a valid priority.\
\fs20 \
\fs28 KERN_FAILURE: \i change_threads\b \i0 \b0 was true and the attempt to change the priority of at least one existing thread failed because the new priority would have exceeded that thread\'27s maximum priority.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task to be resumed.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_resume()\b0 decrements the task\'27s suspend count. If the suspend count becomes 0, all threads with 0 suspend counts in the task are resumed. If the suspend count is already 0, it\'27s not decremented (it never becomes negative).\
\fs20 \
\fs28 \s25 \fs10 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The task has been resumed.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE: The suspend count is already 0.\
\fs20 \
\fs28 KERN_INVALID_ARGUMENT: \i target_task\i0 isn\'27t a task.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task to be suspended (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_suspend()\b0 increments the task\'27s suspend count and stops all threads in the task. As long as the suspend count is positive, newly created threads will not run. This call doesn\'27t return until all threads are suspended.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If the count becomes greater than 1, it will take more than one \b task_resume()\b0 call to restart the task.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task to be destroyed (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_terminate()\b0 destroys the task specified by \i target_task\i0 and all its threads. All resources that are used only by this task are freed. Any port to which this task has receive rights is destroyed.\
\fs20 \
\fs28 \s25 \fs10 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The task has been destroyed.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task to be affected (for example, use \b task_self()\b0 to specify the caller\'27s task).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i thread_list\i0 : Returns the set of threads contained within \i target_task\i0 ; no particular ordering is guaranteed.\
\fs20 \
\fs28 \i thread_count\i0 : Returns the number of threads in \i thread_list\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b task_threads()\b0 gets send rights to the kernel port for each thread contained in \i target_task\i0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The array \i thread_list\i0 is created as a result of this call. You should call \b vm_deallocate()\b0 on this array when the data is no longer needed.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread to be interrupted.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_abort()\b0 aborts page faults and the kernel functions \b msg_send()\b0 , \b msg_receive()\b0 , and \b msg_rpc()\b0 , making the call return a code indicating that it was interrupted. The call is interrupted whether or not the thread (or task containing it) is currently suspended. If it\'27s suspended, the thread receives the interrupt when it resumes.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 A thread will retry an aborted page fault if its state isn\'27t modified before it resumes. The function \b msg_send()\b0 returns SEND_INTERRUPTED; \b msg_receive()\b0 returns RCV_INTERRUPTED; and \b msg_rpc()\b0 returns either SEND_INTERRUPTED or RCV_INTERRUPTED, depending on which half of the RPC was interrupted.\
\fs20 \
\fs28 This function lets one thread stop another thread cleanly, thereby allowing the future execution of the target thread to be controlled in a predictable way. The \b thread_suspend()\b0 function keeps the target thread from executing any further instructions at the user level, including the return from a system call. The \b thread_get_state()\b0 and \b thread_set_state()\b0 functions let you examine or modify the user state of a target thread. However, if a suspended thread was executing within a system call, it also has associated with it a kernel state. This kernel state can\'27t be modified by \b thread_set_state()\b0 ; therefore, when the thread is resumed the system call may return, changing the user state and possibly user memory.\
\fs20 \
\fs28 The \b thread_abort()\b0 function aborts the kernel call from the target thread\'27s point of view by resetting the kernel state so that the thread will resume execution just after the system call. The system call will return one of the interrupted codes described previously. The system call will either be entirely completed or entirely aborted, depending on the precise moment at which the abort was received. Thus if the thread\'27s user state has been changed by \b thread_set_state()\b0 , it won\'27t be modified by any unexpected system call side effects.\
\fs20 \
\fs28 For example, to simulate a UNIX signal, the following sequence of calls may be used:\
\fs28 \s40 \f0 \fs28 2. \fs28 \f1 \b thread_abort()\b0 \'d0Interrupts any system call in progress, setting the return value to \'aainterrupted.\'ba Since the thread is stopped, it won\'27t return to user code.\
\fs20 \
\fs28 \f0 \fs28 3. \fs28 \f1 \b thread_set_state()\b0 \'d0Alters the thread\'27s state to simulate a procedure call to the signal handler.\
\fs20 \
\fs28 \f0 \fs28 4. \fs28 \f1 \b thread_resume()\b0 \'d0Resumes execution at the signal handler. If the thread\'27s stack has been correctly set up, the thread can return to the interrupted system call.\
\fs20 \
\fs28 \s4 \li2116 \fi0 Calling \b thread_abort()\b0 on a thread that\'27s not suspended is risky, since it\'27s difficult to know exactly what system trap, if any, the thread might be executing and whether an interrupt return would cause the thread to do something useful.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_create()\b0 creates a new thread within \i parent_task. \i0 The new thread has no processor state, and has a suspend count of 1. To get a new thread to run, first call \b thread_create()\b0 to get the new thread\'27s identifier, \i child_thread. \i0 Then call \b thread_set_state()\b0 to set a processor state. Finally, call \b thread_resume()\b0 to schedule the thread to execute.\
\fs20 \
\fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important: \b0 \fs28 \f1 Don\'27t use this function unless you\'27re writing a loadable kernel server or implementing a new thread package, such as the C-thread functions. For normal, user-level programming, use \b cthread_fork()\b0 instead. You can then use \b cthread_thread()\b0 if you need to get the Mach thread that corresponds to the new C-thread. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 When the thread is created, send rights to its thread kernel port are given to it and returned to the caller in \i child_thread. \i0 The new thread\'27s exception port is set to PORT_NULL.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_get_special_port()\b0 returns send rights to one of a set of special ports for the thread specified by \i thread. \i0 In the case of getting the thread\'27s own reply port, receive rights are also given to the thread.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b thread_set_special_port()\b0 sets one of a set of special ports for the thread specified by \i thread\i0 .\
\fs20 \
\fs28 The function \b thread_self()\b0 returns the port to which kernel calls for the currently executing thread should be directed. Currently \b thread_self()\b0 returns the thread kernel port, which is a port for which the kernel has receive rights and which it uses to identify a thread. In the future it may be possible for one thread to interpose a port as another thread\'27s kernel port. At that time \b thread_self()\b0 will still return the port to which the executing thread should direct kernel calls, but it may no longer be a port for which the kernel has receive rights.\
\fs20 \
\fs28 If a controller thread has send access to the kernel port of a subject thread, the controller thread can perform kernel operations for the subject thread. Normally only the thread itself and its parent task will have access to the thread kernel port, but any thread may pass rights to its kernel port to any other thread.\
\fs20 \
\fs28 The function \b thread_reply()\b0 returns receive and send rights to the reply port of the calling thread. The reply port is a port to which the thread has receive rights. It\'27s used to receive any initialization messages and as a reply port for early remote procedure calls.\
\fs20 \
\fs28 A thread also has access to its task\'27s special ports.\
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The port was returned or set.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i thread\i0 isn\'27t a thread, or \i which_port\i0 is an invalid port selector.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread whose state is affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of state that\'27s to be manipulated. This may be any one of the following:\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_get_state()\b0 returns the state component (that is, the machine registers) of \i target_thread\i0 as specified by \i flavor. \i0 The \i old_state\i0 is an array of integers that\'27s provided by the caller and returned filled with the specified information. You should set \i old_state_count\i0 to the maximum number of integers in \i old_state\i0 . On return, \i old_state_count\i0 is equal to the actual number of integers in \i old_state\i0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b thread_set_state()\b0 sets the state component of \i target_thread\i0 as specified by \i flavor. \i0 The \i new_state\i0 is an array of integers that the caller fills. You should set \i new_state_count\i0 to the number of elements in \i new_state. \i0 The entire set of registers is reset.\
\fs20 \
\fs28 \i target_thread\i0 must not be \b thread_self()\b0 for either of these calls.\
\fs20 \
\fs28 The state structures are defined in the header file \b mach/machine/thread_status.h\b0 .\
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The state has been set or returned.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 MIG_ARRAY_TOO_LARGE: The returned state is too large for the \i new_state. \i0 The\i new_state\i0 argument is filled in as much as possible, and \i new_state_count\i0 is set to the number of elements that would be returned if there were enough room.\
\fs20 \
\fs28 KERN_INVALID_ARGUMENT: \i target_thread\i0 isn\'27t a thread, \i target_thread\i0 is \b thread_self()\b0 , or \i flavor\i0 is unrecognized for this machine.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread to be affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 : The type of statistics wanted. This can be THREAD_BASIC_INFO or THREAD_SCHED_INFO.\
\fs20 \
\fs28 \i thread_info\i0 : Returns statistics about \i target_thread\i0 .\
\fs20 \
\fs28 \i thread_info_count\i0 : Size of the info structure. This can be THREAD_BASIC_INFO_COUNT or THREAD_SCHED_INFO_COUNT.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_info()\b0 returns the selected information array for a thread, as specified by \i flavor. \i0 The \i thread_info\i0 argument is an array of integers that\'27s supplied by the caller and returned filled with specified information. The \i thread_info_count\i0 argument is supplied as the maximum number of integers in \i thread_info. \i0 On return, it contains the actual number of integers in \i thread_info\i0 . \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The size of the information returned by THREAD_BASIC_INFO is defined by THREAD_BASIC_INFO_COUNT. The definition of the information structure returned by THREAD_BASIC_INFO is:\
\fs28 The \b run_state\b0 field has one of the following values: \
\fs20 \
\fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 TH_STATE_RUNNING: The thread is running normally.\
\fs20 \
\fs28 TH_STATE_STOPPED: The thread is suspended. This happens when the thread or task suspend count is greater than zero. \
\fs20 \
\fs28 TH_STATE_WAITING: The thread is sleeping normally.\
\fs20 \
\fs28 TH_STATE_UNINTERRUPTIBLE: The thread is in an uninterruptible sleep. This should happen only for very short times during some\i \i0 system calls. \
\fs20 \
\fs28 TH_STATE_HALTED: The thread is halted at a clean point. This state happens only after a call to \b thread_abort()\b0 . \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Possible values of the \b flags\b0 field are:\
\fs20 \
\fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 TH_FLAGS_SWAPPED: The thread is swapped out. This happens when the thread hasn\'27t run in a long time, and the kernel stack for the thread has been swapped out. \
\fs20 \
\fs28 TH_FLAGS_IDLE: The thread is the idle thread for the CPU. This means that the CPU runs this thread whenever it has no other threads to run. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b sleep_time\b0 field is useful only when \b run_state\b0 is TH_STATE_STOPPED. (Currently \b sleep_time\b0 is always set to zero, no matter how long the thread has been sleeping.)\
\fs20 \
\fs28 The size of the information returned by THREAD_SCHED_INFO is defined by THREAD_SCHED_INFO_COUNT. The definition of the information structure returned by THREAD_SCHED_INFO is:\
\fs28 The \b policy\b0 field has one of the following values: POLICY_FIXEDPRI, POLICY_TIMESHARE, or POLICY_INTERACTIVE. If \b policy\b0 is POLICY_FIXEDPRI, then \b data\b0 is the quantum (in milliseconds). Otherwise, \b data\b0 is meaningless.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i target_thread\i0 isn\'27t a thread, or \i flavor\i0 isn\'27t recognized, or\i thread_info_count \i0 is smaller than it\'27s supposed to be.\
\fs20 \
\fs28 MIG_ARRAY_TOO_LARGE: The returned info array is too large for \i thread_info. \i0 The\i thread_info\i0 argument is filled as much as possible, and \i thread_info_count\i0 is set to the number of elements that would have been returned if there were enough room.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i thread\i0 : Thread to set policy for.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i policy\i0 : Policy to set. This must be POLICY_TIMESHARE, POLICY_INTERACTIVE, or POLICY_FIXEDPRI.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function changes the scheduling policy for \i thread\i0 to \i policy\i0 . \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i data\i0 argument is meaningless for the timesharing and interactive policies; for the fixed-priority policy, it\'27s the quantum to be used (in milliseconds). The system will always round the quantum up to the next multiple of the basic system quantum (\b min_quantum\b0 , which can be obtained from \b host_info()\b0 ). You can find the current quantum using \b thread_info()\b0 . \
\fs20 \
\fs28 Processor sets can restrict the allowed policies, so this call will fail if the processor set to which \i thread\i0 is currently assigned doesn\'27t permit \i policy\i0 .\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i thread\i0 is not a thread, or \i policy\i0 is not a recognized policy.\
\fs20 \
\fs28 KERN_FAILURE: The processor set to which \i thread\i0 is currently assigned doesn\'27t permit \i policy\i0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Threads have three priorities associated with them by the system: a \i base priority\i0 , a \i maximum priority\i0 , and a \i scheduled priority\i0 . \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The scheduled priority is used to make scheduling decisions about the thread. It\'27s determined from the base priority by the policy. (For the timesharing and interactive policies, this means adding an increment derived from CPU usage). The base priority can be set under user control, but can never exceed the maximum priority. Raising the maximum priority requires presentation of the privileged port for the thread\'27s processor set; since the privileged port for the default processor set is available only to the superuser, users cannot raise their maximum priority to unfairly compete with other users on that set. Newly created threads obtain their base priority from the task and their maximum priority from the thread. \
\fs20 \
\fs28 Priorities range from 0 to 31, where higher numbers denote higher priorities. You can obtain the base, scheduled, and maximum priorities using \b thread_info()\b0 .\
\fs20 \
\fs28 The \b thread_priority()\b0 function changes the base priority and optionally the maximum priority of \i thread\i0 . If the new base priority is higher than the\i \i0 scheduled\i \i0 priority of the currently executing thread, preemption may occur as a result of this call. The maximum priority of the thread is also set if \i set_max\i0 is true. This call fails if \i priority\i0 is greater than the current maximum priority of the thread. As a result, \b thread_priority()\b0 can lower\'d0but never raise\'d0the value of a thread\'27s maximum priority.\
\fs20 \
\fs28 The \b thread_max_priority()\b0 function changes the maximum priority of the thread. Because it requires the privileged port for the processor set, this call can reset the maximum priority to any legal value. If the new maximum priority is less than the thread\'27s base priority, then the thread\'27s base priority is set to the new maximum priority.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i thread\i0 is not a thread, \i processor_set\i0 is not a privileged port for a processor set, or \i priority\i0 is out of range (not in 0-31).\
\fs20 \
\fs28 KERN_FAILURE: The requested operation would violate the thread\'27s maximum (only for \b thread_priority()\b0 ), or the thread is not assigned to the processor set whose privileged port was presented.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread to be resumed.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_resume()\b0 decrements the thread\'27s suspend count. If the count becomes 0, the thread is resumed. If it\'27s still positive, the thread is left suspended. The suspend count never becomes negative.\
\fs20 \
\fs28 \s25 \fs10 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The thread has been resumed.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE: The suspend count is already 0.\
\fs20 \
\fs28 KERN_INVALID_ARGUMENT: \i target_thread\i0 isn\'27t a thread.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread to be suspended.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_suspend()\b0 increments the thread\'27s suspend count and prevents the thread from executing any more user-level instructions. In this context, a user-level instruction is either a machine instruction executed in user mode or a system trap instruction (including page faults).\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If a thread is currently executing within a system trap, the kernel code may continue to execute until it reaches the system return code, or it may suspend within the kernel code. In either case, when the thread is resumed the system trap will return. This could cause unpredictable results if you did a suspend and then altered the user state of the thread in order to change its direction upon a resume. The function \b thread_abort()\b0 lets you abort any currently executing system call in a predictable way.\
\fs20 \
\fs28 If the suspend count becomes greater than 1, it will take more than one \b thread_resume()\b0 call to restart the thread.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i new_thread\i0 : Thread to switch to. If you specify THREAD_NULL, be sure to specify the \i option\i0 argument to be either SWITCH_OPTION_WAIT or SWITCH_OPTION_DEPRESS.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 : Specifies options associated with context switch. Three options are recognized:\
\fs20 \
\fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 SWITCH_OPTION_NONE: No options; the \i time\i0 argument is ignored. (You must set \i new_thread\i0 to a valid thread.)\
\fs20 \
\fs28 SWITCH_OPTION_WAIT: This thread is blocked for the specified time. The block can be aborted by \b thread_abort()\b0 .\
\fs20 \
\fs28 SWITCH_OPTION_DEPRESS: This thread\'27s priority is depressed to the lowest possible value until one of the following happens: \i time\i0 milliseconds pass, this thread is scheduled again, or \b thread_abort()\b0 is called on this thread (whichever happens first). Priority depression is independent of operations that change this thread\'27s priority; for example, \b thread_priority()\b0 will not abort the depression.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i time\i0 : Time duration (in milliseconds\i ) \i0 for options. The minimum time can be obtained as the \b min_timeout\b0 value from \b host_info()\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function provides low-level access to the scheduler\'27s context switching code. \i new_thread\i0 is a hint that implements handoff scheduling. The operating system will attempt to switch directly to \i new_thread\i0 (bypassing the normal logic that selects the next thread to run) if possible. If \i new_thread\i0 isn\'27t valid or THREAD_NULL, \b thread_switch()\b0 returns an error.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b thread_switch()\b0 function is often called when the current thread can proceed no farther for some reason; the various options and arguments allow information about this reason to be transmitted to the kernel. The \i new_thread\i0 argument (handoff scheduling) is useful when the identity of the thread that must make progress before the current thread runs again is known. The SWITCH_OPTION_WAIT option is used when the amount of time that the current thread must wait before it can do anything useful can be estimated and is fairly long. The SWITCH_OPTION_DEPRESS option is used when the required waiting time is fairly short, especially when the identity of the thread that is being waited for is not known.\
\fs20 \
\fs28 Users should beware of calling \b thread_switch()\b0 with an invalid \i new_thread\i0 (for example, THREAD_NULL) and no \i option\i0 . Because the timesharing and interactive schedulers vary the priority of threads based on usage, this may result in a waste of CPU time if the thread that must be run is of lower priority. The use of the SWITCH_OPTION_DEPRESS option in this situation is highly recommended.\
\fs20 \
\fs28 When a thread that\'27s depressed is scheduled, it regains its old priority. The code should recheck the conditions to see if it wants to depress again. If \b thread_abort()\b0 is called on a depressed thread, the priority of the thread is restored.\
\fs20 \
\fs28 Users relying on the preemption semantics of a fixed-priority policy should be aware that \b thread_switch()\b0 ignores these semantics; it will run the specified \i new_thread\i0 independent of its priority and the priority of any other threads that could be run instead.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: \i new_thread\b \i0 \b0 is not a thread, or \i option\i0 is not a recognized option.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_thread\i0 : The thread to be destroyed.\
\fs20 \
\fs28 \s16 \fs10 \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b thread_terminate()\b0 destroys the thread specified by \i target_thread\i0 .\
\fs20 \
\fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning: \b0 \fs28 \f1 Don\'27t use this function on threads that were created using the C-thread functions. Each C thread must terminate itself either explicitly, by calling \b cthread_exit()\b0 , or implicitly, by returning from its top-level function.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE: \i target_task\i0 isn\'27t a valid task. This might be because \i target_task\i0 is a pure Mach task (one created using \b task_create()\b0 ).\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : Task whose virtual memory is to be affected. Use \b task_self()\b0 to allocate memory in the caller\'27s address space.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 : Starting address. If \i anywhere\i0 is true, the input value of this address will be ignored, and the space will be allocated wherever it\'27s available. If \i anywhere\i0 is false, an attempt is made to allocate virtual memory starting at this virtual address. If this address isn\'27t at the beginning of a virtual page, it gets rounded down so that it is. If there isn\'27t enough space at this address, no memory will be allocated. No matter what the value of \i anywhere\i0 is, the address at which memory is actually allocated is returned in \i address\i0 .\
\fs20 \
\fs28 \i size\i0 : Number of bytes to allocate (rounded up by the system to an integral number of virtual pages).\
\fs20 \
\fs28 \i anywhere\i0 : If true, the kernel should find and allocate any region of the specified size. If false, virtual memory is allocated starting at \i address\i0 (rounded down to a virtual page boundary) if sufficient space exists.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_allocate()\b0 allocates a region of virtual memory, placing it in the address space of the specified task. The physical memory isn\'27t actually allocated until the new virtual memory is referenced. By default, the kernel rounds all addresses down to the nearest page boundary and all memory sizes up to the nearest page size. The global variable \b vm_page_size\b0 contains the page size. For languages other than C, the value of \b vm_page_size\b0 can be obtained by calling \b vm_statistics()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Initially, the pages of allocated memory are protected to allow all forms of access, and are inherited in child tasks as a copy. Subsequent calls to \b vm_protect()\b0 and \b vm_inherit()\b0 may be used to change these properties. The allocated region is always zero-filled.\
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 Unless you have a special reason for calling \b vm_allocate()\b0 (such as a need for page-aligned memory), you should usually call \b malloc()\b0 or a similar C library function instead. The C library functions don\'27t necessarily make UNIX or Mach system calls, so they\'27re generally faster than using a Mach function such as \b vm_allocate()\b0 . \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task whose virtual memory is to be affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i source_address\i0 : The address in \i target_task\i0 of the start of the source range (must be a page boundary).\
\fs20 \
\fs28 \i size\i0 : The number of bytes to copy (must be a multiple of \b vm_page_size\b0 ). \
\fs20 \
\fs28 \i dest_address\i0 : The address in \i target_task\i0 of the start of the destination range (must be a page boundary).\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_copy()\b0 causes the source memory range to be copied to the destination address; the destination region must not overlap the source region. The destination address range must already be allocated and writable; the source range must be readable. \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For languages other than C, the value of \b vm_page_size\b0 can be obtained by calling \b vm_statistics()\b0 .\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: The address doesn\'27t start on a page boundary or the size isn\'27t a multiple of \b vm_page_size\b0 .\
\fs20 \
\fs28 KERN_PROTECTION_FAILURE: The destination region isn\'27t writable, or the source region isn\'27t readable.\
\fs20 \
\fs28 KERN_INVALID_ADDRESS: An illegal or nonallocated address was specified, or insufficient memory was allocated at one of the addresses.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : Task whose virtual memory is to be affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 : Starting address (must be on a page boundary).\
\fs20 \
\fs28 \i size\i0 : The number of bytes to deactivate (must be a multiple of \b vm_page_size\b0 ). Specifying 0 deactivates all of the task\'27s memory at or above \i address\i0 .\
\fs20 \
\fs28 \i when\i0 : A mask specifying how aggressively the system should deactivate the memory, and whether the memory should be deactivated if it\'27s shared. Values for \i when\i0 are defined in the header file \b mach/vm_policy.h\b0 .\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function lets you tell the operating system that a region of memory won\'27t be used for a long time. It differs from \b vm_deallocate()\b0 in that the task\'27s mapping to the memory is retained; only the physical memory associated with the region is affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 A \i when\i0 value of VM_DEACTIVATE_NOW is the most extreme\'d0the system will immediately place clean pages at the front of the free list, and dirty pages at the front of the inactive list. A \i when\i0 value of VM_DEACTIVATE_SOON specifies that the system should place all pages on the tail of the inactive list. You can add the mask VM_DEACTIVATE_SHARED to indicate that only shared memory should be affected.\
\fs20 \
\fs28 This call is used in the window server to deactivate the backing stores of windows in hidden applications, and is used in the Application Kit to deactivate the text, data, and stack of hidden applications.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_deallocate()\b0 relinquishes access to a region of a task\'27s address space, causing further access to that memory to fail. This address range will be available for reallocation. Note that because of the rounding to virtual page boundaries, more than \i size\i0 bytes may be deallocated. Use \b vm_statistics()\b0 or the global variable \b vm_page_size\b0 to get the current virtual page size.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 This function may be used to deallocate memory that was passed to a task in a message (using out-of-line data). In that case, the rounding should cause no trouble, since the region of memory was allocated as a set of pages.\
\fs20 \
\fs28 The function \b vm_deallocate()\b0 affects only the task specified by \i target_task. \i0 Other tasks that may have access to this memory can continue to reference it.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : Task whose virtual memory is to be affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 : Starting address (this gets rounded down to a page boundary).\
\fs20 \
\fs28 \i size\i0 : Size in bytes of the region for which inheritance is to change (this gets rounded up to a page boundary).\
\fs20 \
\fs28 \i new_inheritance\i0 : How this memory is to be inherited in child tasks. Inheritance is specified by using one of these following three values:\
\fs20 \
\fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 VM_INHERIT_SHARE: Child tasks will share this memory with this task.\
\fi0 VM_INHERIT_COPY: Child tasks will receive a copy of this region.\
\fi0 VM_INHERIT_NONE: This region will be absent from child tasks.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_inherit()\b0 specifies how a region of a task\'27s address space is to be passed to child tasks at the time of task creation. Inheritance is an attribute of virtual pages; thus the addresses and size of memory to be set will be rounded to refer to whole pages.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Setting \b vm_inherit()\b0 to VM_INHERIT_SHARE and forking a child task is the only way two Mach tasks can share physical memory. However, all the threads of a given task share all the same memory.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : Task whose virtual memory is to be affected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 : Starting address (this gets rounded down to a page boundary).\
\fs20 \
\fs28 \i size\i0 : Size in bytes of the region for which protection is to change (this gets rounded up to a page boundary).\
\fs20 \
\fs28 \i set_maximum\i0 : If set, make the protection change apply to the maximum protection associated with this address range; otherwise, change the current protection on this range. If the maximum protection is reduced below the current protection, both will be changed to reflect the new maximum.\
\fs20 \
\fs28 \i new_protection\i0 : A new protection value for this region; either VM_PROT_NONE or some combination of VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_protect()\b0 changes the protection of some pages of allocated memory in a task\'27s address space. In general, a protection value permits the named operation. When memory is first allocated it has all protection bits on. The exact interpretation of a protection value is machine-dependent. In the NeXT Mach operating system, three levels of memory protection are provided: \
\fs28 VM_PROT_NONE permits no access. VM_PROT_WRITE permits read, execute, and write access; VM_PROT_READ or VM_PROT_EXECUTE permits read and execute access, but not write access. \
\fi0 r = vm_protect(task_self(), addr, vm_page_size, FALSE, 0);\
\fi0 if (r != KERN_SUCCESS) \{\
\fi0 mach_error("vm_protect 0", r);\
\fi0 exit(1);\
\fi0 \}\
\fi0 printf("protect on\\n");\
\s25 \fi-2015 \f1 \fs28 \fs28 \
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The memory has been protected.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_PROTECTION_FAILURE: An attempt was made to increase the current or maximum protection beyond the existing maximum protection value.\
\fs20 \
\fs28 KERN_INVALID_ADDRESS: An illegal or nonallocated address was specified.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_read()\b0 allows one task\'27s virtual memory to be read by another task. The data array is returned in a newly allocated region; the task reading the data should call \b vm_deallocate()\b0 on this region when it\'27s done with the data.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For languages other than C, the value of \b vm_page_size\b0 can be obtained by calling \b vm_statistics()\b0 .\
\fs28 \f0 \b \fs20 RETURN \b0 \fs28 \f1 KERN_SUCCESS: The memory has been read.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: Either \i address\i0 does not start on a page boundary or \i size\i0 isn\'27t an integral number of pages.\
\fs20 \
\fs28 KERN_NO_SPACE: There isn\'27t enough room in the caller\'27s virtual memory to allocate space for the data to be returned.\
\fs20 \
\fs28 KERN_PROTECTION_FAILURE: The address region in the target task is protected against reading.\
\fs20 \
\fs28 KERN_INVALID_ADDRESS: An illegal or nonallocated address was specified, or there were not \i size\i0 bytes of data following that address.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i target_task\i0 : The task for which an address space description is requested.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 : The address at which to start looking for a region. On return, \i address\i0 will contain the start of the region (therefore, the value returned will be different from the value that was passed in if the specified region is part of a larger region).\
\fs20 \
\fs28 \i size\i0 : Returns the size (in bytes) of the located region.\
\fs20 \
\fs28 \i protection\i0 : Returns the current protection of the region.\
\fs20 \
\fs28 \i max_protection\i0 : Returns the maximum allowable protection for this region.\
\fs20 \
\fs28 \i inheritance\i0 : Returns the inheritance attribute for this region.\
\fs20 \
\fs28 \i shared\i0 : Returns true if this region is shared, false if it isn\'27t.\
\fs20 \
\fs28 \i object_name\i0 : Returns the port identifying the region\'27s memory object.\
\fs20 \
\fs28 \i offset\i0 : Returns the offset into the pager object at which this region begins.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The \b vm_region()\b0 function returns a description of the specified region of the target task\'27s virtual address space. This function begins at \i address\i0 , looking forward through memory until it comes to an allocated region. (If \i address\i0 is in a region, that region is used.) If \i address\i0 isn\'27t in a region, it\'27s set to the start of the first region that follows the incoming value. In this way an entire address space can be scanned. You can set \i address\i0 to the constant VM_MIN_ADDRESS (defined in the header file \b mach/machine/vm_param.h\b0 ) to specify the first address in the address space. \
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 char *data;\
\fi0 kern_return_t r;\
\fi0 vm_size_t size;\
\fi0 vm_prot_t protection, max_protection;\
\fi0 vm_inherit_t inheritance;\
\fi0 boolean_t shared;\
\fi0 port_t object_name;\
\fi0 vm_offset_t offset;\
\fi0 vm_address_t address; \
\pard \s14 \li2116 \fi0 \ri503 \ql \
/* . . . */\
\fi0 /* Check the inheritance of "data". */\
\fi0 address = (vm_address_t)&data;\
\fi0 r = vm_region(task_self(), &address, &size, &protection, \
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function lets you control the paging policy for a region of memory. In addition to its normal paging policy, the system can control the placement of pages under certain patterns of access. These patterns are currently limited to strictly sequential access in either direction.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i policy\i0 mask can have the following values, which can be combined:\
\'b7 VM_POLICY_RANDOM (don\'27t use a special paging policy)\
\pard \s37 \li2116 \fi0 \ri1007 \ql \fs20 \
\fs28 \f0 \b \fs28 Note: \b0 \fs28 \f1 The page-ahead policy isn\'27t currently implemented.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Calls to \b vm_policy()\b0 affect memory at the backing store level, not the mapping level. For example, calling \b vm_policy()\b0 on a memory-mapped file affects the underlying file, and consequently all uses of that file. It is currently impossible for different users of the same file to have different policies for that file.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_statistics()\b0 returns statistics about the kernel\'27s use of virtual memory since the kernel was booted. The system page size is contained in both the \b pagesize\b0 field of the \i vm_status\i0 and the global variable \b vm_page_size\b0 , which is set at task initialization and remains constant for the life of the task.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b vm_write()\b0 allows a task\'27s virtual memory to be written by another task. For languages other than C, the value of \b vm_page_size\b0 can be obtained by calling \b vm_statistics()\b0 .\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT: The address doesn\'27t start on a page boundary, or the size isn\'27t an integral number of pages.\
\fs20 \
\fs28 KERN_PROTECTION_FAILURE: The address region in the target task is protected against writing.\
\fs20 \
\fs28 KERN_INVALID_ADDRESS: An illegal or nonallocated address was specified or the amount of allocated memory starting at \i address\i0 was less than \i data_count\i0 .\
\fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 The Bootstrap Server, like the Network Name Server, lets tasks publish ports that other tasks can send messages to. Unlike the Network Name Server, the Bootstrap Server is designed so that each server and its clients must be on the same host. The Bootstrap Server accomplishes this by using each task\'27s bootstrap port (which is inherited from its parent) to ensure that the task is a descendent of a local task. \
\fs20 \
\fs28 When a task forks a child task that shouldn\'27t have access to the same set of services as the parent, the parent task must change its own bootstrap port\'d0perhaps only temporarily\'d0so that its child inherits a \i subset port\i0 . The parent should then change the set of services available on the subset port to suit the child\'27s requirements.\
\fs20 \
\fs28 The Bootstrap Server was created by NeXT, so these functions aren\'27t in other versions of Mach. See \b /NextDeveloper/Headers/servers/bootstrap.defs\b0 for more information of how the Bootstrap Server works.\
\fs20 \
\fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note: \b0 \fs28 \f1 If possible, you should use Distributed Objects instead of the Bootstrap Server. The Distributed Objects system is described in the \i NEXTSTEP General Reference\i0 .\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 : The string that names the service.\
\fs20 \
\fs28 \i service_port\i0 : Returns receive rights to the service port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Use this function in a server to start providing a service. The service must already be defined, either by the appropriate line in \b /etc/bootstrap.conf\b0 or by a call to \b bootstrap_create_service()\b0 . Calling \b bootstrap_check_in()\b0 makes the service active. \
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 /* Get receive rights for our service. */\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 : The string that specifies the service.\
\fs20 \
\fs28 \i service_port\i0 : Returns send rights for the service.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Creates a service named \i service_name\i0 and returns send rights to that port in \i service_port\i0 . The port may later be checked in as if this port were configured in the bootstrap configuration file. (At that time \b bootstrap_check_in()\b0 will return receive rights to \i service_port \i0 and will make the service active.)\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 This function is often used to create services that are available only to a subset of tasks (see \b bootstrap_subset()\b0 ). Any task can call this function\'d0it doesn\'27t have to be the server.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_names\i0 : Returns the names of all known services.\
\fs20 \
\fs28 \i service_names_count\i0 : Returns the number of service names.\
\fs20 \
\fs28 \i server_names\i0 : Returns the name, if known, of the server that provides the corresponding service. Except for the \b mach_init\b0 server, this name isn\'27t known unless the bootstrap configuration file has a \b server\b0 line for this server.\
\fs20 \
\fs28 \i server_names_count\i0 : Returns the number of server names.\
\fs20 \
\fs28 \i service_active\i0 : Returns an array of booleans that correspond to the \i service_names\i0 array. For each item, the boolean value is true if the service is receiving messages sent to its port; otherwise, it\'27s false.\
\fs20 \
\fs28 \i service_active_count\i0 : Returns the number of items in the \i service_active\i0 array.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function returns information about all services that are known. Note that it won\'27t return information on services that are defined only in subsets, unless the subset port is an ancestor of \i bootstrap_port\i0 . (See \b bootstrap_subset()\b0 for information on subsets.)\
\fs20 \
\fs28 \s18 \f2 \fs24 \fs10 \
\fs24 \f0 \b \fs20 EXAMPLE \b0 \fs24 \f2 result = bootstrap_info(bootstrap_port, &service_names, &service_cnt,\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 : The string that identifies the service.\
\fs20 \
\fs28 \i service_port\i0 : Returns send rights for the service port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns send rights for the service port of the specified service. The service isn\'27t guaranteed to be active. (To check whether the service is active, use \b bootstrap_status()\b0 .)\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_UNKNOWN_SERVICE: The service doesn\'27t exist. It might be defined in a subset (see \b bootstrap_subset()\b0 ).\
\fs20 \
\fs28 Returns appropriate kernel errors on RPC failure. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_names\i0 : An array of service names.\
\fs20 \
\fs28 \i service_names_count\i0 : The number of service names.\
\fs20 \
\fs28 \i service_ports\i0 : Returns an array of service ports. \
\fs20 \
\fs28 \i service_ports_count\i0 : Returns the number of service ports. This should be equal to \i service_names_count\i0 .\
\fs20 \
\fs28 \i all_services_known\i0 : Returns true if every service name was recognized; otherwise returns false.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns port send rights in corresponding entries of the array \i service_ports\i0 for all services named in the array \i service_names\i0 . You should call \b vm_deallocate()\b0 on \i service_ports\i0 when you no longer need it.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Unknown service names have the corresponding service port set to PORT_NULL. Note that these services might be available in a subset (see \b bootstrap_subset()\b0 ).\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_BAD_COUNT: \i service_names_count\i0 was too large (greater than BOOTSTRAP_MAX_LOOKUP_COUNT, which is defined in the header file \b server/bootstrap_defs.h\b0 ).\
\fs20 \
\fs28 Returns appropriate kernel errors on RPC failure. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 : The string that identifies the service.\
\fs20 \
\fs28 \i service_port\i0 : The service port for the service.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 You can use this function to create a server that hasn\'27t been defined in the bootstrap configuration file. This function specifies to the Bootstrap Server exactly which port should be the service port.\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can\'27t register a service if an active binding already exists. However, you can register a service if the existing binding is inactive (that is, the Bootstrap Server currently holds receive rights for the service port); in this case the previous service port will be deallocated. \
\fs20 \
\fs28 A service that is restarting can resume service for previous clients by setting \i service_port\i0 to the previous service port. You can get this port by calling \b bootstrap_check_in()\b0 .\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 : The string that specifies a particular service.\
\fs20 \
\fs28 \i service_active\i0 : Returns true if the service is active; otherwise, returns false.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 This function tells you whether a service is known to users of \i bootstrap_port\i0 , and whether it\'27s active. A service is active if a server is able to receive messages on its service port. If a service isn\'27t active, the Bootstrap Server holds receive rights for the service port.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_UNKNOWN_SERVICE: The service doesn\'27t exist. It might be defined in a subset (see \b bootstrap_subset()\b0 ).\
\fs20 \
\fs28 Returns appropriate kernel errors on RPC failure. \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i bootstrap_port\i0 : A bootstrap port. Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i requestor_port\i0 : A port that determines the life span of the subset. \
\fs20 \
\fs28 \i subset_port\i0 : Returns the subset port.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 Returns a new port to use as a bootstrap port. This port behaves exactly like the previous \i bootstrap_port\i0 , with one exception: When you register a port by calling \b bootstrap_register()\b0 using \i subset_port\i0 as the bootstrap port, the registered port is available only to users of \i subset_port\i0 and its descendants. Lookups on the \i subset_port\i0 will return ports registered specifically with this port, and will also return ports registered with ancestors of this \i subset_port\i0 . (The ancestors of \i subset_port\i0 are \i bootstrap_port\i0 and, if \i bootstrap_port\i0 is itself a subset port, any ancestors of \i bootstrap_port\i0 .) \
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can override a service already registered with an ancestor port by registering it with the subset port. Any thread that looks up the service using the subset port will see only the version of the service that\'27s registered with the subset port. This is one way to transparently provide services such as monitor programs or individualized spelling checkers, while the rest of the system still uses the default service. \
\fs20 \
\fs28 When it's detected that \i requestor_port\i0 is destroyed, the subset port and its descendants are destroyed; the services advertised by these ports are destroyed, as well.\
\fs20 \
\fs28 \pard \s14 \li2116 \fi0 \ri503 \ql \f2 \fs24 /* Get and save the current bootstrap port for this task. */\
\fi0 r = task_get_bootstrap_port(task_self(), &old_bs_port);\
\fi0 if (r != KERN_SUCCESS) \{\
\fi0 mach_error("task_get_bootstrap_port", r);\
\fi0 exit(1);\
\fi0 \} \
\fi0 /* Get a subset port. */\
\fi0 r = bootstrap_subset(old_bs_port, task_self(), &subset_port);\
\fi0 if (r != BOOTSTRAP_SUCCESS) \{\
\fi0 mach_error("Couldn't get unpriv port", r);\
\fi0 exit(1);\
\fi0 \}\
\fi0 \
/* Set the bootstrap port */\
\fi0 r = task_set_bootstrap_port(task_self(), subset_port);\
\fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 If possible, you should use Distributed Objects instead of the Network Name Server functions. The Distributed Objects system is described in the \i NEXTSTEP General Reference\i0 . \
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i server_port\i0 : The task\'27s port to the Network Name Server. To use the system Network Name Server, this should be set to the global variable \b name_server_port\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : The name of the port to be checked in.\
\fs20 \
\fs28 \i signature\i0 : The port used to protect the right to remove a name.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b netname_check_in()\b0 enters a port with the name \i port_name\i0 into the name space of the local network server. The \i signature\i0 argument is a port that\'27s used to protect this name. This same port must be presented on a \b netname_check_out()\b0 call for that call to be able to remove the name from the name space.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i server_port\i0 : The task\'27s port to the Network Name Server. To use the system Network Name Server, this should be set to \b name_server_port\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : The name of the port to be checked out.\
\fs20 \
\fs28 \i signature\i0 : The port used to protect the right to remove a name.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b netname_check_out()\b0 removes a port with the name \i port_name\i0 from the name space of the local network server. The \i signature\i0 argument must be the same port as the signature port passed to \b netname_check_in()\b0 when this name was checked in.\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 NETNAME_NOT_YOURS: The signature given to \b netname_check_out()\b0 did not match the signature with which the port was checked in.\
\fs28 \f0 \b \fs20 ARGUMENTS \b0 \fs28 \f1 \i server_port\i0 : The task\'27s port to the Network Name Server. To use the system Network Name Server, this should be set to \b name_server_port\b0 .\
\fs20 \
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i host_name\i0 : The name of the host to query. This can\'27t be a null pointer.\
\fs20 \
\fs28 \i port_name\i0 : The name of port to be looked up.\
\fs20 \
\fs28 \i port_id\i0 : The port that was looked up.\
\fs28 \f0 \b \fs20 DESCRIPTION \b0 \fs28 \f1 The function \b netname_look_up()\b0 returns the value of the port named by \i port_name\i0 by questioning the host named by the \i host_name\i0 argument. Thus this call is a directed name lookup. The \i host_name\i0 may be any of the host\'27s official nicknames. If it\'27s an empty string, the local host is assumed. If \i host_name\i0 is \'aa\b *\b0 \'ba, a broadcast lookup is performed.\
\fs20 \
\fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important: \b0 \fs28 \f1 Use \b NXPortNameLookup()\b0 instead of \b netname_look_up()\b0 in all NEXTSTEP applications. (In the future, Listener instances might register with a server other than the Network Name Server.)\
\fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 NETNAME_NOT_CHECKED_IN: \b netname_look_up()\b0 could not find the name at the given host.\
\fs20 \
\fs28 NETNAME_NO_SUCH_HOST: The \i host_name\i0 argument to \b netname_look_up()\b0 does not name a valid host.\
\fs20 \
\fs28 NETNAME_HOST_NOT_FOUND: \b netname_look_up()\b0 could not reach the host named by \i host_name\i0 (for instance, because it\'27s down).\